package Controller;

import DataAccess.DataAccessFacade;
import DomainModel.ClassWork;
import DomainModel.ClassWorkType;
import DomainModel.Role;
import DomainModel.Section;
import DomainModel.User;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 *
 * @author ReynierO
 * @date Nov 11, 2013
 */
public class EnterClassWorkController extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("currentUser");

        if (user == null || user.getRole() != Role.PROF) {
           request.getRequestDispatcher("/login").forward(request, response);
       }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
        
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("currentUser");

        try {
            loadClassWorkTypes(request);
                    
            int sectionId = Integer.valueOf(request.getParameter("sid"));
            String strClassWorkId = request.getParameter("cwid");
            request.setAttribute("sectionId", sectionId);
            int classWorkId = (strClassWorkId == null || strClassWorkId.isEmpty()) ? 0 : Integer.valueOf(strClassWorkId);
            
            Section section = DataAccessFacade.getInstance().getSectionByIdAndUser(sectionId, user.getUserId());
            request.setAttribute("section", section);
            
            if (classWorkId > 0) {
                loadClassWork(request, user, classWorkId);
            }
            request.getRequestDispatcher("/WEB-INF/grs/enterClassWork.jsp").forward(request, response);
        } catch (Exception e) {
        } finally {
        }
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
        
        String sectionId = request.getParameter("sectionId");
        String actionSubmitClassWork = request.getParameter("submitClassWork");
        String actionCancelSubmitClassWork = request.getParameter("cancelSubmitClassWork");
                
        if (actionCancelSubmitClassWork != null) { // CANCEL submitting a class work
            response.sendRedirect("viewClassWorks?sid=" + sectionId);
        }
        else if (actionSubmitClassWork != null) { // Submit class work
            if (doAddClassWork(request, response)) {
                response.sendRedirect("viewClassWorks?sid=" + sectionId);
            }
            else {
                request.setAttribute("classWorkTypes", request.getParameter("classWorkTypes"));
                request.getRequestDispatcher("/WEB-INF/grs/enterClassWork.jsp").forward(request, response);
            }
        }
    }
    
    /**
     * @autor ReynierO
     * @date 11/13/2013
     * Loads the class work types as JSON into a hidden field "classWorkTypes"
     * @param request
     * @throws Exception 
     */
    private void loadClassWorkTypes(HttpServletRequest request) throws Exception {
        List<ClassWorkType> classWorkTypes = DataAccessFacade.getInstance().getClassWorkTypess();
        JSONArray classWorkTypesJson = new JSONArray();

        for (ClassWorkType classWorkType : classWorkTypes) {
            JSONObject classWorkJson = new JSONObject();

            classWorkJson.put("classWorkTypeId", classWorkType.getClassWorkTypeId());
            classWorkJson.put("classWorkTypeName", classWorkType.getClassWorkTypeName());

            classWorkTypesJson.put(classWorkJson);
        }
        
        request.setAttribute("classWorkTypes", classWorkTypesJson.toString());
    }
    
    private void loadClassWork(HttpServletRequest request, User professor, int classWorkId) throws Exception {
        ClassWork classWork = DataAccessFacade.getInstance().getClassWorkById(professor.getUserId(), Integer.valueOf(classWorkId));

        DateFormat dbDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateFormat dueDateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
        Date dueDate = dbDateFormat.parse(classWork.getDueDate());
            
        request.setAttribute("inputClassWorkId", classWorkId);
        request.setAttribute("inputClassWorkTypeId", classWork.getClassWorkType().getClassWorkTypeId());
        request.setAttribute("inputClassWorkName", classWork.getName());
        request.setAttribute("inputDueDate", dueDateFormat.format(dueDate));
        request.setAttribute("inputMaxPoints", classWork.getMaxPoints());
        request.setAttribute("inputWeight", classWork.getWeight());
    }
    
    /**
     * @autor ReynierO
     * Process add/edit class work
     * @param request
     * @param response 
     */
    private boolean doAddClassWork(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> messages = new HashMap<>();
        request.setAttribute("messages", messages);
            
        try {
            String strClassWorkId = request.getParameter("inputClassWorkId");
            String strClassWorkTypeId = request.getParameter("inputClassWorkType");
            String strClassWorkName = request.getParameter("inputClassWorkName");
            String strClassWorkDueDate = request.getParameter("inputDueDate");
            String strClassWorkMaxPoints = request.getParameter("inputMaxPoints");
            String strClassWorkWeight = request.getParameter("inputWeight");
            int classWorkId = (strClassWorkId == null || strClassWorkId.isEmpty()) ? 0 : Integer.valueOf(strClassWorkId);
            int sectionId = Integer.valueOf(request.getParameter("sectionId"));
            int maxPoints = (strClassWorkMaxPoints == null || strClassWorkMaxPoints.isEmpty()) ? 0 : Integer.valueOf(strClassWorkMaxPoints);
            double weight = (strClassWorkWeight == null || strClassWorkWeight.isEmpty()) ? 0 : Double.valueOf(strClassWorkWeight);

            request.setAttribute("inputClassWorkId", strClassWorkId);
            request.setAttribute("inputClassWorkTypeId", strClassWorkTypeId);
            request.setAttribute("inputClassWorkName", strClassWorkName);
            request.setAttribute("inputDueDate", strClassWorkDueDate);
            request.setAttribute("inputMaxPoints", strClassWorkMaxPoints);
            request.setAttribute("inputWeight", strClassWorkWeight);
        
            String missingFields = "";
            if (strClassWorkTypeId == null || strClassWorkTypeId.isEmpty()) missingFields += missingFields.isEmpty() ? "Type" : ", Type";
            if (strClassWorkName == null || strClassWorkName.isEmpty()) missingFields += missingFields.isEmpty() ? "Name" : ", Name";
            if (strClassWorkDueDate == null || strClassWorkDueDate.isEmpty()) missingFields += missingFields.isEmpty() ? "Due Date" : ", Due Date";
            if (strClassWorkMaxPoints == null || strClassWorkMaxPoints.isEmpty()) missingFields += missingFields.isEmpty() ? "Max Points" : ", Max Points";
            if (strClassWorkWeight == null || strClassWorkWeight.isEmpty()) missingFields += missingFields.isEmpty() ? "Weight" : ", Weight";
            
            if (!missingFields.isEmpty()) {
                HttpSession session = request.getSession();
                User user = (User) session.getAttribute("currentUser");
                DataAccessFacade dataAccessFacade = DataAccessFacade.getInstance();
                Section section = dataAccessFacade.getSectionByIdAndUser(sectionId, user.getUserId());
                request.setAttribute("sectionId", sectionId);
                request.setAttribute("section", section);
            
                messages.put("error", "Please provide the following fields: " + missingFields);
                return false;
            }
            
            DateFormat dbDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            DateFormat dueDateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
            Calendar cal = Calendar.getInstance();
            Date dueDate = dueDateFormat.parse(strClassWorkDueDate);
            
            ClassWorkType classWorkType = new ClassWorkType(Integer.parseInt(strClassWorkTypeId), "");
            ClassWork classWork = new ClassWork(classWorkId, classWorkType, sectionId, strClassWorkName, maxPoints, dbDateFormat.format(cal.getTime()), dbDateFormat.format(dueDate), weight);
            DataAccessFacade.getInstance().setClassWork(classWork);
            
            String msg = (classWorkId == 0) ? "Class work added successfully." : "Class work edited successfully.";
            messages.put("success", msg);
        } catch (Exception e) {
            messages.put("error", "An error occurred adding the class work.");
            return false;
        }
        
        return true;
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
